﻿//会再次封装CJSByteArray
//说明：这是一个数据包的类，每次存取一个数据包的内容。
//这个类最大的局限性在于，每次必须按照数据包的格式封包，解包的时候也只能按包的格式一步一步解析，否则会出错。
#ifndef _MSG_H_
#define _MSG_H_

#include "jsbytearray.h"

#define MSGLENGTH 1024*1024

/////////////////////////////////////////////////////////////////////
#define MSG_FLAG_APPLY		0
#define MSG_FALG_REPLY		1
/*
 *   以下四个宏是type字段中在掩码
 */
#define TYPEFLAGMASK	0X80000000
#define MODIDMASK		0X7F000000
#define SUBMODIDMASK	0X00FF0000
#define MESSAGEIDMASK	0X0000FFFF

/*
 *  下面参数宏对type字段进行填充与解析
 */
#define INITTYPE(type)          ( type&=0 )//初始化type字段
#define SETTYPEFLAG(type)		(type |= TYPEFLAGMASK)//flag=1
#define RESETTYPEFLAG(type)		(type &= ~TYPEFLAGMASK)//flag=0

#define GETTYPEFLAG(type)				(((type)&TYPEFLAGMASK)>>31)//取type中flag字段

#define GETMODID(type)					(((type)&MODIDMASK)>>24)// get module id
#define PUTMODID(type,modId)			(type |=(modId<<24))//put module id into type

#define GETSUBMODID(type)				(((type)&SUBMODIDMASK)>>16)//get submodule id
#define	PUTSUBMODID(type,subModId)		(type |=(subModId)<<16)//put submodule id into type

#define GETMESSAGEID(type)				((type)&MESSAGEIDMASK)//get message id
#define	PUTMESSAGEID(type,messageId)	(type |=messageId)//put message id into type

int CreateType(int flag,int modID,int subModID,int messageID);
void GetType(int type,int *flag,int *modID,int *subModID,int *messageID);

class CJSMsg
{
public:
    CJSMsg();
    CJSMsg(const CJSMsg& msg);
    //************************************************
    //构建数据包头，如果知道数据包长度，则可以给出，不知道的话，可以不给，len默认一个比较大的值
    //************************************************
    CJSMsg(int type, int len);
    ~CJSMsg();

    //************************************************
    //说明：把从网络接收到的数据包放入Msg类中。
    //返回值：返回实际放入的长度，-1出错。
    //************************************************
    int PutMsg(char str[], int nLen);

    //************************************************
    //说明：把封好的数据包，以char*返回，放到网络上来发送
    //返回值：NULL为出错
    //************************************************
    char* GetMsg(void);

    //************************************************
    //说明：解包函数，针对TLV数据包格式。
    //************************************************
    int Type(void);
    int Length(void);

    //解包开始必须掉用
    void UnPackBegin(void);

    //************************************************
    //说明：取整个数据包的长度。注意与Length()函数的区别。
    //Length()----TLV(Type/Length/Value)中的L.指的是V的长度
    //MsgLength()---指的是TLV的总长度。
    //关系：MsgLength() == Length() + sizeof(TL)
    //************************************************
    int MsgLength(void);
    int Clear(void);

    //************************************************
    //说明：数据包封装完闭的时候调用。主要是重置数据包的长度
    //************************************************
    int End(void);
    CJSMsg& operator=(const CJSMsg& msg);

    CJSByteArray* GetByteArray(void);

private:
    CJSByteArray *m_pByteArray;
};

#endif //_MSG_H_



